package cn.wuweixiang.springbootdemo;

import cn.wuweixiang.springbootdemo.filter.DemoFilter;
import cn.wuweixiang.springbootdemo.listener.DemoListener;
import cn.wuweixiang.springbootdemo.servlet.DemoServlet;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.boot.web.servlet.ServletComponentScan;
import org.springframework.boot.web.servlet.ServletListenerRegistrationBean;
import org.springframework.boot.web.servlet.ServletRegistrationBean;
import org.springframework.context.annotation.Bean;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * 一、基本配置：
 * 1.1、入口类
 * Spring Boot通常有一个名为 *Application的入口类，对应有有一个入口方法main(),main()使用SpringApplication.run(*Application.class, args);
 * 1.2、@SpringBootApplication
 * Spring Boot的核心注解，它是一个组合注解，包含了：
 * @EnableAutoConfiguration 自动载入应用程序所需的所有Bean[这依赖于Spring Boot在类路径中的查找]：
 * 添加了spring-boot-starter-web依赖，会自动添加Tomcat和SpringMVC的依赖，那么Spring Boot会对Tomcat和SpringMVC进行自动配置
 * @SpringBootConfiguration 说明这是一个配置文件类，就像xml配置文件，而现在是用java配置文件
 * @ComponentScan basePackages：指定扫描的包，basePackageClasses：指定扫描的类
 *
 * 二、外部配置：properties配置的属性名会覆盖yml相同配置的属性名
 * 	2.0、命令行参数配置：java -jar xx.jar --server.port=9090 # 修改Tomcat端口号
 * 	2.1、常规属性配置
 * 	@see SpringBootDemoApplication#username
 * 	2.2、类型安全配置
 *  @see SpringBootDemoApplication#password
 *
 * 三、日志配置
 * 默认情况下，Spirng Boot使用Logback作为日志框架
 *
 * @author weixiang.wu
 */
@RestController
@SpringBootApplication
@ConfigurationProperties(prefix = "wwx")
/**
 * 在Spring Boot中，当需要以注解的方式添加session监听器或其他servlet(包括监听器、过滤器、以及自定义的servlet)时，
 * 为了让其生效，还需要在配置类上添加@ServletComponentScan注解，该注解的作用是告诉spring boot,让其自动管理servlet，否则注解方式注册的servlet不起作用
 */
@ServletComponentScan
public class SpringBootDemoApplication {
	/**
	 * 常规属性配置：在Spring Boot 中，我们只需要在application.properties定义属性，直接使用@Value注入即可
	 */
	@Value("${wwx.username}")
	private String username;

	/**
	 * 类型安全配置：@ConfigurationProperties指定前缀，set注入
	 */
	private String password;
	public void setPassword(String password) {
		this.password = password;
	}

	@GetMapping("/")
	public String index() {
		System.out.println("my username is [" + username + "] and my password is [" + password + "]");
		return "my username is [" + username + "] and my password is [" + password + "]";
//		Console:my username is [wuweixiang] and my password is [123456]
	}


	/**
	 * 注册Servlet. 不需要添加注解：@ServletComponentScan
	 * @return
	 */
	@Bean
	public ServletRegistrationBean demoServlet(){
		ServletRegistrationBean registrationBean = new ServletRegistrationBean();
		registrationBean.setServlet(new DemoServlet());
		registrationBean.addUrlMappings("/demoServlet");
		return registrationBean;
	}

	/**
	 * 1.使用FilterRegistrationBean注册Filter，只需要在@Configuration类中加入即可
	 * 2.直接使用@WebFilter
	 * @see DemoFilter
	 * @return
	 */
//	@Bean
//	public FilterRegistrationBean demoFilter() {
//		FilterRegistrationBean demoFilter = new FilterRegistrationBean();
//		demoFilter.addUrlPatterns("/*");
//		demoFilter.setFilter(new DemoFilter());
//		return demoFilter;
//	}

	/**
	 *  1.使用ServletListenerRegistrationBean注册Listener，只需要在@Configuration类中加入即可
	 *  2.直接使用@WebFilter
	 * @return
	 */
//	@Bean
//	public ServletListenerRegistrationBean<DemoListener> myServletListener() {
//		ServletListenerRegistrationBean<DemoListener> demoListener = new ServletListenerRegistrationBean<DemoListener>();
//		demoListener.setListener(new DemoListener());
//		return demoListener;
//	}

	public static void main(String[] args) {
		SpringApplication.run(SpringBootDemoApplication.class, args);
	}
}
